﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.templates;
using l1cs.server.datatables;
using l1cs.server.model.skill;
using l1cs.server.model.map;
using l1cs.server.model.Instance;
using System.Reflection;
using l1cs.server.serverpackets;

namespace l1cs.server.model
{
    public class L1EffectSpawn
    {
        private static Logger _log = Logger.getLogger( typeof( L1EffectSpawn ).FullName );

        private static L1EffectSpawn _instance;

        //    private Constructor _constructor;

        private L1EffectSpawn()
        {
        }

        public static L1EffectSpawn getInstance()
        {
            if ( _instance == null )
            {
                _instance = new L1EffectSpawn();
            }
            return _instance;
        }

        /// <summary>
        /// エフェクトオブジェクトを生成し設置する
        /// </summary>
        /// <param name="npcId">エフェクトNPCのテンプレートID</param>
        /// <param name="time">存在時間(ms)</param>
        /// <param name="locX">設置する座標X</param>
        /// <param name="locY">設置する座標Y</param>
        /// <param name="mapId">設置するマップのID</param>
        /// <returns>生成されたエフェクトオブジェクト</returns>
        public L1EffectInstance spawnEffect( int npcId, int time, int locX, int locY, short mapId )
        {
            return spawnEffect( npcId, time, locX, locY, mapId, null, 0 );
        }

        public L1EffectInstance spawnEffect( int npcId, int time, int locX,
                int locY, short mapId, L1PcInstance user, int skiiId )
        {
            L1Npc template = NpcTable.getInstance().getTemplate( npcId );
            L1EffectInstance effect = null;

            if ( template == null )
            {
                return null;
            }

            effect = (L1EffectInstance)NpcTable.getInstance().newNpcInstance( template );
            effect.setId( IdFactory.getInstance().nextId() );
            effect.setGfxId( template.get_gfxid() );
            effect.setX( locX );
            effect.setY( locY );
            effect.setHomeX( locX );
            effect.setHomeY( locY );
            effect.setHeading( 0 );
            effect.setMap( mapId );
            effect.setUser( user );
            effect.setSkillId( skiiId );
            L1World.getInstance().storeObject( effect );
            L1World.getInstance().addVisibleObject( effect );

            foreach ( L1PcInstance pc in L1World.getInstance().getRecognizePlayer( effect ) )
            {
                effect.addKnownObject( pc );
                pc.addKnownObject( effect );
                pc.sendPackets( new S_NPCPack( effect ) );
                pc.broadcastPacket( new S_NPCPack( effect ) );
            }
            L1NpcDeleteTimer timer = new L1NpcDeleteTimer( effect, time );
            timer.begin();

            return effect;
        }

        public void doSpawnFireWall( L1Character cha, int targetX, int targetY )
        {
            L1Npc firewall = NpcTable.getInstance().getTemplate( 81157 ); // ファイアーウォール
            int duration = SkillsTable.getInstance().getTemplate( L1SkillId.FIRE_WALL ).getBuffDuration();

            if ( firewall == null )
            {
                throw new NullReferenceException( "FireWall data not found:npcid=81157" );
            }

            L1Character l1base = cha;
            for ( int i = 0; i < 8; i++ )
            {
                int a = l1base.targetDirection( targetX, targetY );
                int x = l1base.getX();
                int y = l1base.getY();
                if ( a == 1 )
                {
                    x++;
                    y--;
                }
                else if ( a == 2 )
                {
                    x++;
                }
                else if ( a == 3 )
                {
                    x++;
                    y++;
                }
                else if ( a == 4 )
                {
                    y++;
                }
                else if ( a == 5 )
                {
                    x--;
                    y++;
                }
                else if ( a == 6 )
                {
                    x--;
                }
                else if ( a == 7 )
                {
                    x--;
                    y--;
                }
                else if ( a == 0 )
                {
                    y--;
                }
                if ( !l1base.isAttackPosition( x, y, 1 ) )
                {
                    x = l1base.getX();
                    y = l1base.getY();
                }
                L1Map map = L1WorldMap.getInstance().getMap( cha.getMapId() );
                if ( !map.isArrowPassable( x, y, cha.getHeading() ) )
                {
                    break;
                }

                L1EffectInstance effect = spawnEffect( 81157, duration * 1000, x, y,
                        cha.getMapId() );
                if ( effect == null )
                {
                    break;
                }
                foreach ( L1Object objects in L1World.getInstance().getVisibleObjects( effect, 0 ) )
                {
                    if ( objects is L1EffectInstance )
                    {
                        L1EffectInstance npc = (L1EffectInstance)objects;
                        if ( npc.getNpcTemplate().get_npcId() == 81157 )
                        {
                            npc.deleteMe();
                        }
                    }
                }
                if ( targetX == x && targetY == y )
                {
                    break;
                }
                l1base = effect;
            }
        }
    }
}
